# -*- coding: utf-8 -*-
import random
import requests
import os
import pandas as pd
from req_report.data import OpneData as od

"""
接口单元测试，单独验证接口的场景
需要传一个正确的  传参模板

"""


def get_file_path(file_name):
    """
    获取 文件的路径
    :param file_name: 文件名称（带后缀）
    :return: 文件绝对路径
    """
    try:
        # 指定查找范围
        current_dir = os.path.dirname(os.path.abspath("./"))  # 获取当前项目的路径
        # 获取指定目录下所有文件的路径
        for root, dirs, files in os.walk(current_dir):  # 遍历查找范围下所有目录
            for file in files:
                if file == file_name:
                    # 拼接文件路径
                    file_path = os.path.join(root, file)
                    # 获取文件的绝对路径
                    absolute_path = os.path.abspath(file_path)
                    # 打印文件路径
                    file_path = absolute_path.replace('\\', '\\\\')
                    return file_path
    except Exception as e:
        raise e


def key_verify(url, method, body: dict, json_body: dict, header, body_list):
    """
    验证删除字段场景
    :param url:
    :param method:
    :param body:
    :param json_body:
    :param header:
    :param body_list:
    :return:
    """
    result = []
    # 删除字段场景
    body1 = ''
    json_body1 = ''
    if body:
        body1 = body.copy()
    elif json_body:
        json_body1 = json_body.copy()

    try:
        if body1:
            for i in range(len(body1)):
                key = body_list[i][0]
                value = body_list[i][1]
                bb = body1.copy()
                del bb[key]  # 删除报文字段
                res = requests.request(url=url, method=method, headers=header, data=bb)
                result.append(f'删除字段{body_list[i][0]}')
                result.append(f'请求入参{bb}')
                result.append(f'结果：\n' + f'{res.json()}')
        elif json_body1:
            for i in range(len(json_body1)):
                key = body_list[i][0]
                value = body_list[i][1]
                bb = json_body1.copy()
                del bb[key]  # 删除报文字段
                res = requests.request(url=url, method=method, headers=header, json=bb)
                result.append(f'删除字段{body_list[i][0]}')
                result.append(f'请求入参{bb}')
                result.append(f'结果：\n' + f'{res.json()}')


    except:
        result.append(f'删除字段{body_list[i][0]}')
        result.append(f'请求入参{bb}')
        result.append('结果：\n' + '接口报错')

    return result


def key_verify_2(url, method, header):
    """
    不存在字段
    :param url:
    :param method:
    :param header:
    :return:
    """
    result = []
    random_char = random.choice('abcdefghijklmnopqrstuvwxyz!@#$%^&*()')
    body = {f'{random_char}': f'{random_char}'}
    json_body = {f'{random_char}': f'{random_char}'}
    try:
        res = requests.request(url=url, method=method, headers=header, json=json_body)
        result.append(f'请求报文错误——json')
        result.append(f'请求入参{json_body}')
        result.append('结果：\n' + f'{res.json()}')

    except:
        result.append(f'请求报文错误——json')
        result.append(f'请求入参{json_body}')
        result.append('结果：\n' + '接口报错')

    try:
        res2 = requests.request(url=url, method=method, headers=header, data=body)
        result.append(f'请求报文错误——data')
        result.append(f'请求入参{body}')
        result.append('结果：\n' + f'{res2.json()}')

    except:
        result.append(f'请求报文错误——data')
        result.append(f'请求入参{body}')
        result.append('结果：\n' + '接口报错')
    return result


def key_verify_3(url, method, body, json_body, header, body_list):
    """
    单个字段请求
    :param url:
    :param method:
    :param header:
    :return:
    """
    result = []
    body1 = ''
    json_body1 = ''
    if body:
        body1 = body.copy()
        data = body1
        for i in range(len(data)):
            key = body_list[i][0]
            value = body_list[i][1]
            data1 = {f'{key}': f'{value}'}
            try:
                res = requests.request(url=url, method=method, headers=header, data=data1)
                result.append(f'请求报文为单个字段{key}')
                result.append(f'请求入参{data1}')
                result.append('结果：\n' + f'{res.json()}')

            except:
                result.append(f'请求报文为单个字段{key}')
                result.append(f'请求入参{data1}')
                result.append('结果：\n' + '接口报错')
    elif json_body:
        json_body1 = json_body.copy()
        data = json_body1
        for i in range(len(data)):
            key = body_list[i][0]
            value = body_list[i][1]
            data1 = {f'{key}': f'{value}'}

            try:
                res = requests.request(url=url, method=method, headers=header, json=data1)
                result.append(f'请求报文为单个字段{key}')
                result.append(f'请求入参{data1}')
                result.append('结果：\n' + f'{res.json()}')
            except:
                result.append(f'请求报文为单个字段{key}')
                result.append(f'请求入参{data1}')
                result.append('结果：\n' + '接口报错')
    return result


def value_verify_1(url, method, body: dict, json_body: dict, header, body_list):
    """
    验证请求字段值为空场景
    :param url:
    :param method:
    :param body:
    :param json_body:
    :param header:
    :param body_list:
    :return:
    """
    result = []
    # 请求字段值为空
    body1 = ''
    json_body1 = ''
    if body:
        body1 = body.copy()
    elif json_body:
        json_body1 = json_body.copy()
    try:
        if body1:
            for i in range(len(body1)):
                key = body_list[i][0]
                value = body_list[i][1]
                aa = body1.copy()
                aa.update({key: ''})  # 更新报文字段值为空
                res = requests.request(url=url, method=method, headers=header, data=aa)
                result.append(f'请求字段{body_list[i][0]}为空')
                result.append(f'请求入参{aa}')
                result.append('结果：\n' + f'{res.json()}')
        elif json_body1:
            for i in range(len(json_body1)):
                key = body_list[i][0]
                value = body_list[i][1]
                aa = json_body1.copy()
                aa.update({key: ''})  # 更新报文字段值为空
                res = requests.request(url=url, method=method, headers=header, json=aa)
                result.append(f'请求字段{body_list[i][0]}为空')
                result.append(f'请求入参{aa}')
                result.append('结果：\n' + f'{res.json()}')


    except:
        result.append(f'请求字段{body_list[i][0]}为空')
        result.append(f'请求入参{aa}')
        result.append('结果：\n' + '接口报错')

    return result


def value_verify_2(url, method, body: dict, json_body: dict, header, body_list):
    """
    验证请求值错误（带特殊字符）
    :param url:
    :param method:
    :param body:
    :param json_body:
    :param header:
    :param body_list:
    :return:
    """
    result = []
    # 请求字段值错误（特殊字符）
    body1 = ''
    json_body1 = ''
    if body:
        body1 = body.copy()
    elif json_body:
        json_body1 = json_body.copy()
    try:
        if body1:
            for i in range(len(body1)):
                key = body_list[i][0]
                value = body_list[i][1]
                random_char = random.choice('abcdefghijklmnopqrstuvwxyz!@#$%^&*()')
                aa = body1.copy()
                aa.update({key: f'{random_char}！'})  # 更新报文字段值
                res = requests.request(url=url, method=method, headers=header, data=aa)
                result.append(f'请求字段{body_list[i][0]}错误')
                result.append(f'请求入参{aa}')
                result.append('结果：\n' + f'{res.json()}')
        elif json_body1:
            for i in range(len(json_body1)):
                key = body_list[i][0]
                value = body_list[i][1]
                random_char = random.choice('abcdefghijklmnopqrstuvwxyz!@#$%^&*()')
                aa = json_body1.copy()
                aa.update({key: f'{random_char}！'})  # 更新报文字段值
                res = requests.request(url=url, method=method, headers=header, json=aa)
                result.append(f'请求字段{body_list[i][0]}错误')
                result.append(f'请求入参{aa}')
                result.append('结果：\n' + f'{res.json()}')



    except:
        result.append(f'请求字段{body_list[i][0]}错误')
        result.append(f'请求入参{json_body1}{body1}')
        result.append('结果：\n' + '接口报错')

    return result


def null_body_verify(url, method, header):
    """
    请求报文为空场景
    :param url:
    :param method:
    :param header:
    :return:
    """
    result = []
    body = {}
    json_body = {}
    try:
        res = requests.request(url=url, method=method, headers=header, json=json_body)
        result.append(f'请求报文为空——json')
        result.append(f'请求入参{json_body}')
        result.append('结果：\n' + f'{res.json()}')

    except:
        result.append(f'请求报文为空——json')
        result.append(f'请求入参{json_body}')
        result.append('结果：\n' + '接口报错')

    try:
        res2 = requests.request(url=url, method=method, headers=header, data=body)
        result.append(f'请求报文为空——data')
        result.append(f'请求入参{body}')
        result.append('结果：\n' + f'{res2.json()}')

    except:
        result.append(f'请求报文为空——data')
        result.append(f'请求入参{body}')
        result.append('结果：\n' + '接口报错')

    return result


def req_verify(url, method, header, remark, body: dict = '', json_body: dict = '', **kwargs):
    """
    验证单接口常规校验场景（缺少字段/字段错误/字段值空/字段值错/请求报文为空）
    :param url:
    :param method:
    :param body:
    :param json_body:
    :param header:
    :return:
    """

    try:

        # 报文切换成list
        body_list = []
        if body:
            for key, value in body.copy().items():
                body_list.append([key, value])
        elif json_body:
            for key, value in json_body.copy().items():
                body_list.append([key, value])

        # 场景
        result1 = key_verify(url, method, body=body, json_body=json_body, header=header,
                             body_list=body_list)  # 验证删除字段场景
        result2 = value_verify_1(url, method, body=body, json_body=json_body, header=header,
                                 body_list=body_list)  # 验证请求字段值为空场景
        result3 = value_verify_2(url, method, body=body, json_body=json_body, header=header,
                                 body_list=body_list)  # 验证请求值错误（带特殊字符）
        result4 = null_body_verify(url, method, header)  # 请求报文为空场景
        result5 = key_verify_2(url, method, header)  # 不存在字段
        result6 = key_verify_3(url, method, body=body, json_body=json_body, header=header,
                               body_list=body_list)  # 验证单独传一个字段

        # 整合报告
        results = []
        for i in range(0, len(result1), 3): results.append(result1[i:i + 3])
        for i in range(0, len(result2), 3): results.append(result2[i:i + 3])
        for i in range(0, len(result3), 3): results.append(result3[i:i + 3])
        for i in range(0, len(result4), 3): results.append(result4[i:i + 3])
        for i in range(0, len(result5), 3): results.append(result5[i:i + 3])
        for i in range(0, len(result6), 3): results.append(result6[i:i + 3])

        results.append(['url', f'{url}'])
        results.append(['总入参 data', f'{body}'])
        results.append(['总入参 json_body', f'{json_body}'])
        results.append(['备注', f'{remark}'])

        # 创建 DataFrame
        df = pd.DataFrame(results)

        # 自定义列顺序
        # df = df[['验证删除字段场景', '验证请求字段值为空场景']]

        file_name = url.split('/')[-1]
        for i in range(10):
            aa = get_file_path(f'{file_name}_{i}.xlsx')
            if aa:
                continue
            else:
                pass
            file_name = f'{file_name}_{i}'
            break
        current_dir = os.path.dirname(os.path.abspath(__file__))  # 获取当前文件所在目录
        file_path = f'{current_dir}/report/{file_name}.xlsx'
        # 保存到 Excel
        with pd.ExcelWriter(file_path, engine='openpyxl') as writer:
            df.to_excel(writer, index=False, sheet_name=f'{file_name}')
    except Exception as e:
        print(e)
    finally:
        print(file_name, "已结束")


# 查询蔗区分组
req_verify(url=od.host + od.get_group_url, method='post', json_body=od.get_group, header=od.header,
           remark=od.get_group_r)